#include "tim_hw.h"
#include "gd32e10x_timer.h"
#include "string.h"


extern uint32_t SystemCoreClock;

tim1Ms_DataTypeDef	tag1Ms={0};

/*
初始化定时器
*/
void initTimer68uS(void)
{
	timer_parameter_struct timer_initpara;
	
	rcu_periph_clock_enable(RCU_TIMER2);

	timer_deinit(TIMER2);
	/* initialize TIMER init parameter struct */
	timer_struct_para_init(&timer_initpara);
	/* TIMER2 configuration */
	timer_initpara.prescaler         = (SystemCoreClock / 1000000)-1;
	timer_initpara.alignedmode       = TIMER_COUNTER_EDGE;
	timer_initpara.counterdirection  = TIMER_COUNTER_UP;
	timer_initpara.period            = 68-1;
	timer_initpara.clockdivision     = TIMER_CKDIV_DIV1;
	timer_init(TIMER2, &timer_initpara);

  nvic_irq_enable(TIMER2_IRQn, 2, 0);
	
	/* enable the TIMER interrupt */
	timer_interrupt_flag_clear(TIMER2, TIMER_INT_FLAG_UP);
	timer_interrupt_enable(TIMER2, TIMER_INT_UP);
	
	
	
	timer_enable(TIMER2);
}
/*
初始化1ms定时器，16位
*/
void InitTimer1MS(void)
{
	//const uint32_t osc = 8000000;
	/* ----------------------------------------------------------------------------
	TIMER1 Configuration: 
	TIMER1CLK = SystemCoreClock/12000 = 10KHz.
	TIMER1 configuration is timing mode, and the timing is (30000/10000 = 3s).
	---------------------------------------------------------------------------- */

	timer_parameter_struct timer_initpara;
	

	rcu_periph_clock_enable(RCU_TIMER1);

	timer_deinit(TIMER1);
	/* initialize TIMER init parameter struct */
	timer_struct_para_init(&timer_initpara);
	/* TIMER1 configuration */
	timer_initpara.prescaler         = (SystemCoreClock / Sec_div_def)-1;
	timer_initpara.alignedmode       = TIMER_COUNTER_EDGE;
	timer_initpara.counterdirection  = TIMER_COUNTER_UP;
	timer_initpara.period            = 0xFFFF;
	timer_initpara.clockdivision     = TIMER_CKDIV_DIV1;
	timer_init(TIMER1, &timer_initpara);


	//timer_interrupt_enable(TIMER1, TIMER_INT_UP);
	timer_enable(TIMER1);
		
		
	//configure the TIMER1 interrupt
	//nvic_priority_group_set(NVIC_PRIGROUP_PRE2_SUB2);
  //nvic_irq_enable(TIMER1_IRQn, 1, 1);
}


/*
初始化时间相关变量
*/
void initTime1MsVar(void)
{
	memset(&tag1Ms, 0, sizeof(tag1Ms));
}



/*
获取两个时间差，不要超过32秒
一般用于ms级别的精确延时
输入参数：get1sCounter
返回结果：新旧timer的毫秒差

注意毫秒延时，在启用休眠后会导致误差最大0.4秒
即比之前预计的延时时间延长了0.4秒
*/
uint16_t getTim1MsElaps(uint16_t newT, uint16_t oldT)
{
	uint16_t tempDa;

	if (newT >= oldT)
	{
		tempDa = newT - oldT;
	}
	else
	{
		tempDa = 0xffff - oldT + newT + 1;
	}

	return tempDa;

}



/*
时间变量处理
得出一个秒信号
*/
void Deal_Time(void)
{
	uint16_t ulTim1ms;
	uint32_t TempDa;

	ulTim1ms = get1msCounter();

	if (ulTim1ms != tag1Ms.Tim1msOld)
	{
		tag1Ms.Tim1msOld = ulTim1ms;

		TempDa = getTim1MsElaps(ulTim1ms, tag1Ms.Tim1000msOld);
		TempDa += tag1Ms.s_ms;
		if (TempDa >= Sec_div_def)
		{
			tag1Ms.valid = 1;
			tag1Ms.s += TempDa/Sec_div_def;
			tag1Ms.s_ms = TempDa%Sec_div_def; //waste no millisecond
			tag1Ms.Tim1000msOld = ulTim1ms;
			
			#if 0	//时间测试
			{	static uint8_t testSta = 0;
				 //可以让LED亮1秒，灭1秒
				if (testSta == 0x00)
				{
					testSta = 0x01;
					led_light_on();
				}
				else
				{
					testSta = 0x00;
					led_light_off();
				}
			}
			#endif
		}
	}
}


/*
返回系统秒
*/
//uint32_t get1sCounter(void)
//{
//	return tag1Ms.s;
//}


/*
此处单独为休眠启动一个定时器
5秒
为了休眠更省电，同时保证看门狗不复位
注，看门狗是6秒复位
*/
void StartLongTimerForWakeup(void)
{
	timer_parameter_struct timer_initpara;
	uint16_t myPrescaler, myTimCntInit;
	
	
	rcu_periph_clock_enable(RCU_TIMER0);

	timer_deinit(TIMER0);
	/* initialize TIMER init parameter struct */
	timer_struct_para_init(&timer_initpara);
	
	{
		myPrescaler = SystemCoreClock / 10000;
		myTimCntInit = 15535;
	}
	
	/* TIMER1 configuration */
	timer_initpara.prescaler         = myPrescaler-1;
	timer_initpara.alignedmode       = TIMER_COUNTER_EDGE;
	timer_initpara.counterdirection  = TIMER_COUNTER_UP;
	timer_initpara.period            = 0xffff;
	timer_initpara.clockdivision     = TIMER_CKDIV_DIV1;
	timer_init(TIMER0, &timer_initpara);


	//为了计时0.4秒，需要先给counter写入一个初值
	//计算方法：8M主频prescaler分频，要计时0.4秒，系统时钟要走8M* 0.4个tick
	//3200000使用prescaler  = 80分频，相当于timer要走40000
	timer_counter_value_config(TIMER0, myTimCntInit);
	
	timer_interrupt_enable(TIMER0, TIMER_INT_UP);
	timer_enable(TIMER0);
	
	
	
		
	//configure the TIMER1 interrupt
	nvic_priority_group_set(NVIC_PRIGROUP_PRE2_SUB2);
  nvic_irq_enable(TIMER0_UP_TIMER9_IRQn, 2, 1);
}


/*
此处单独为休眠启动一个定时器
0.4秒
因为系统秒时间需要连续，根据采样定理，为了保证1秒至少采样2次，所以规定休眠时间为0.4秒
*/
void StartTimerForWakeup(void)
{
	timer_parameter_struct timer_initpara;
	uint16_t myPrescaler, myTimCntInit;
	
	
	rcu_periph_clock_enable(RCU_TIMER0);

	timer_deinit(TIMER0);
	/* initialize TIMER init parameter struct */
	timer_struct_para_init(&timer_initpara);
	
//	if (SystemCoreClock == 8000000)	//8M 主频对应设置
//	{
//		myPrescaler = 80;
//		myTimCntInit = 25535;
//		
//	}
//	else	if (SystemCoreClock == 120000000)//此处对应120M 主频
//	{
//		myPrescaler = 1200;
//		myTimCntInit = 25535;
//	}
//	else
	{
		myPrescaler = SystemCoreClock / 1000000;
		myTimCntInit = 25535;
	}
	
	/* TIMER1 configuration */
	timer_initpara.prescaler         = myPrescaler-1;
	timer_initpara.alignedmode       = TIMER_COUNTER_EDGE;
	timer_initpara.counterdirection  = TIMER_COUNTER_UP;
	timer_initpara.period            = 0xffff;
	timer_initpara.clockdivision     = TIMER_CKDIV_DIV1;
	timer_init(TIMER0, &timer_initpara);


	//为了计时0.4秒，需要先给counter写入一个初值
	//计算方法：8M主频prescaler分频，要计时0.4秒，系统时钟要走8M* 0.4个tick
	//3200000使用prescaler  = 80分频，相当于timer要走40000
	timer_counter_value_config(TIMER0, myTimCntInit);
	
	timer_interrupt_enable(TIMER0, TIMER_INT_UP);
	timer_enable(TIMER0);
	
	
	
		
	//configure the TIMER1 interrupt
	nvic_priority_group_set(NVIC_PRIGROUP_PRE2_SUB2);
  nvic_irq_enable(TIMER0_UP_TIMER9_IRQn, 2, 1);
}

/*
停止休眠对应的定时器
*/
void StopTimerForWakeup(void)
{
	timer_interrupt_disable(TIMER0, TIMER_INT_UP);
	timer_disable(TIMER0);
}


void delay(uint32_t cnt)
{
	if (cnt == 0) return;
	
	while(cnt--);
	
}




